﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Northwind.Repositories;
using Northwind.Repositories.Entity;
using Lib.Web.Mvc.JQuery.JqGrid;
using jqGrid.DungDepTrai.Models;
using Northwind.Model;
using System.IO;
using Lib.Web.Mvc;

namespace jqGrid.DungDepTrai.Controllers
{
    public class HomeController : Controller
    {
        #region Fields
        IEmployeesRepository _employeesRepository;
        #endregion

        #region Constructors
        public HomeController()
            : this(new EmployeesRepository())
        {
        }

        public HomeController(IEmployeesRepository employeesRepository)
        {
            _employeesRepository = employeesRepository;
        }
        #endregion

        #region Actions
        public ViewResult Employees()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult FindEmployees(JqGridRequest request)
        {
            int totalRecordsCount = _employeesRepository.GetCount();

            JqGridResponse response = new JqGridResponse()
            {
                TotalPagesCount = (int)Math.Ceiling((float)totalRecordsCount / (float)request.RecordsCount),
                PageIndex = request.PageIndex,
                TotalRecordsCount = totalRecordsCount
            };
            response.Records.AddRange(from employee in _employeesRepository.FindRange(String.Format("{0} {1}", request.SortingName, request.SortingOrder), request.PageIndex * request.RecordsCount, request.RecordsCount)
                                      select new JqGridRecord<EmployeeViewModel>(Convert.ToString(employee.Id), new EmployeeViewModel(employee)));

            return new JqGridJsonResult() { Data = response };
        }

        [NoCache]
        public ActionResult EmployeePhoto(int id)
        {
            //We should keep images in file system
            string employeePhotoPath = GetEmployeePhotoPath(id);
            if (!System.IO.File.Exists(employeePhotoPath))
            {
                Employee employee = _employeesRepository.FindByKey(id);
                if (employee.Photo != null)
                {
                    using (FileStream employeePhotoStream = new FileStream(employeePhotoPath, FileMode.Create, FileAccess.Write))
                        //Skip Ole bytes array
                        employeePhotoStream.Write(employee.Photo, 78, employee.Photo.Length - 78);
                }
                else
                    return new EmptyResult();
            }
            return File(employeePhotoPath, "image/bmp");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ContentResult InsertEmployee([Bind(Exclude = "Id")]EmployeeViewModel viewModel, HttpPostedFileBase photo)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (photo != null && photo.ContentLength > 0 && photo.ContentType != "image/bmp")
                        return Content("Photo must be in BMP format.");
                    else
                    {
                        Employee employee = new Employee();
                        employee.LastName = viewModel.LastName;
                        employee.Notes = viewModel.Notes;
                        employee.Title = viewModel.Title;
                        employee.TitleOfCourtesy = viewModel.TitleOfCourtesy;
                        employee.FirstName = viewModel.FirstName;
                        _employeesRepository.Add(ref employee);

                        _employeesRepository.SaveChanges();

                        photo.SaveAs(GetEmployeePhotoPath(employee.Id));
                    }
                }
                catch
                {
                    //There should be some decent exception handling here
                    return Content("An error occurred during employee insert.");
                }

                return Content("success");
            }
            else
                return Content("Invalid employee data.");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ContentResult UpdateEmployee(EmployeeViewModel viewModel, HttpPostedFileBase photo)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    Employee employee = _employeesRepository.FindByKey(viewModel.Id);
                    if (employee != null)
                    {
                        if (photo != null && photo.ContentLength > 0)
                        {
                            if (photo.ContentType == "image/bmp")
                                photo.SaveAs(GetEmployeePhotoPath(viewModel.Id));
                            else
                                return Content("Photo must be in BMP format.");
                        }

                        employee.LastName = viewModel.LastName;
                        employee.Notes = viewModel.Notes;
                        employee.Title = viewModel.Title;
                        employee.TitleOfCourtesy = viewModel.TitleOfCourtesy;
                        employee.FirstName = viewModel.FirstName;

                        _employeesRepository.SaveChanges();
                    }
                    else
                        return Content("Couldn't found employee for update.");
                }
                catch
                {
                    //There should be some decent exception handling here
                    return Content("An error occurred during employee update.");
                }

                return Content("success");
            }
            else
                return Content("Invalid employee data.");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public HttpStatusCodeResult DeleteEmployee(int id)
        {
            try
            {
                _employeesRepository.Delete(id);
                _employeesRepository.SaveChanges();

                return new HttpStatusCodeResult(200, "Succeeded");
            }
            catch
            {
                //There should be some decent exception handling here
                return new HttpStatusCodeResult(500, "An error occurred during employee delete.");
            }    
        }
        #endregion

        #region Methods
        private string GetEmployeePhotoPath(int id)
        {
            string northwindPhotosPath = Server.MapPath("~/Content/Northwind/");
            if (!Directory.Exists(northwindPhotosPath))
                Directory.CreateDirectory(northwindPhotosPath);

            return Path.Combine(northwindPhotosPath, String.Format("EmployeePhoto_{0}.bmp", id));
        }
        #endregion
    }
}
